package dao;

import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import org.springframework.jdbc.core.simple.ParameterizedBeanPropertyRowMapper;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;
//import javax.annotation.Resource;
import java.util.List;
import java.util.Map;


/**
 * User: cheny
 * Date: 2010-6-11
 * Time: 22:11:13
 */
@Component
public class BaseDao {
    //@Resource
    private DataSource dataSource;

    private SimpleJdbcTemplate getSimpleJdbcTemplate() {
        return new SimpleJdbcTemplate(dataSource);
    }

    public int insert(String sql, Object object) {
        SqlParameterSource ps = new BeanPropertySqlParameterSource(object);
        KeyHolder keyHolder = new GeneratedKeyHolder();
        getSimpleJdbcTemplate().getNamedParameterJdbcOperations().update(sql, ps, keyHolder);
        return keyHolder.getKey().intValue();
    }

    public int update(String sql, Object object) {
        return getSimpleJdbcTemplate().update(sql, new BeanPropertySqlParameterSource(object));
    }


    //==========================selectForObject============================
    public <T> T selectForObject(String sql, Class<T> clazz, Object... args) {
        return args.length > 1 || clazz != args.getClass() ?
                selectForObjectByArgs(sql, clazz, args) :
                selectForObjectByObject(sql, clazz, args);
    }

    private <T> T selectForObjectByArgs(String sql, Class<T> clazz, Object... args) {
        List<T> list = selectForListByArgs(sql, clazz, args);
        return list.size() == 0 ? null : list.get(0);
    }

    private <T> T selectForObjectByObject(String sql, Class<T> clazz, Object object) {
        List<T> list = selectForListByObject(sql, clazz, object);
        return list.size() == 0 ? null : list.get(0);
    }

    public <T> T selectForObject(String sql, Class<T> clazz, Map<String, Object> map) {
        List<T> list = selectForList(sql, clazz, map);
        return list.size() == 0 ? null : list.get(0);
    }


    //==========================selectForList============================
    public <T> List<T> selectForList(String sql, Class<T> clazz, Object... args) {
        return args.length > 1 || clazz != args.getClass() ?
                selectForListByArgs(sql, clazz, args) :
                selectForListByObject(sql, clazz, args);
    }

    private <T> List<T> selectForListByArgs(String sql, Class<T> clazz, Object... args) {
        RowMapper<T> rm = ParameterizedBeanPropertyRowMapper.newInstance(clazz);
        return getSimpleJdbcTemplate().query(sql, rm, args);
    }

    private <T> List<T> selectForListByObject(String sql, Class<T> clazz, Object object) {
        SqlParameterSource ps = new BeanPropertySqlParameterSource(object);
        RowMapper<T> rm = ParameterizedBeanPropertyRowMapper.newInstance(clazz);
        return getSimpleJdbcTemplate().query(sql, rm, ps);
    }

    public <T> List<T> selectForList(String sql, Class<T> clazz, Map<String, Object> map) {
        RowMapper<T> rm = ParameterizedBeanPropertyRowMapper.newInstance(clazz);
        return getSimpleJdbcTemplate().query(sql, rm, map);
    }

}
